nochmal SCORE

← Zurück zum Forum

Ich hatte ja schon mal hier im Forum und dann im vorletzten Heft über die Score-Darstellung berichtet. Leider ist die Methode mit Nutzung des Dezimalmodus im Beispiel eher unvollständig. Das Problem dabei ist, daß man nur maximal den Wert 99 zum Score addieren kann und Subtraktion ist gar nicht implementiert. Irgendwie mag ich es auch nicht so zu rechnen... also werde ich hier an dieser Stelle eine Routine entwickeln, die eine ganz normale 16-Bit Zahl in Ziffern umwandelt. Da eine 16-Bit Zahl maximal den Wert 65536 annehmen kann, brauchen wir also auch nur 5 Ziffern. Wir müssen also x mal mit 10000 subtrahieren, x mal mit 1000, x mal mit 100 .... etc um die einzelnen Ziffern zu bekommen. Eine andere und bessere Methode sehe ich derzeit nicht.

        ; converts 5 digits (16 bit values have max. 5 decimal digits)
    .local hex2dec16
        ldx #0
l3      jsr div10
        sta result,x
        inx
        cpx #5
        bne l3
        rts

        ; divides a 16 bit value by 10
        ; remainder is returned in akku
div10
        ldy #16         ; 16 bits
        lda #0
        clc
l4      rol
        cmp #10
        bcc skip
        sbc #10
skip    rol value
        rol value+1
        dey
        bpl l4
        rts

value   .he 00 00

result  .byte 0,0,0,0,0
    .endl

value ist die 16-Bit Zahl, die Du wandeln möchtest, in Result steht dann das Ergebnis - result hat die 1er, result+1 die 10er usw. .

PP´s of STARSOFTBerlin____github|meine Webseite|Demozoo

Nur für den Fall, dass jemand auch 32 Bit benötigt...

        ; converts 10 digits (32 bit values have max. 10 decimal digits)
    .local hex2dec32
        ldx #0
l3      jsr div10
        sta result,x
        inx
        cpx #10
        bne l3
        rts

        ; divides a 32 bit value by 10
        ; remainder is returned in akku
div10
        ldy #32         ; 32 bits
        lda #0
        clc
l4      rol
        cmp #10
        bcc skip
        sbc #10
skip    rol value
        rol value+1
        rol value+2
        rol value+3
        dey
        bpl l4
        rts

value   .he 00 00 00 00

result  .byte 0,0,0,0,0,0,0,0,0,0
    .endl

PP´s of STARSOFTBerlin____github|meine Webseite|Demozoo

Moin!

Ich nutze dafür eine Routine, die eine Binärzahl bitweise analysiert.

Nehmen wir als Beispiel eine 8-Bit-Zahl: 1000 0001​ Dies entspricht im Dezimalwert 2^7+2^0=129

Betrachten wir die Binärzahl 1000 0001​ Die oberste 1 steht für 2^7 (oder 2222222), während die unterste 1 dem Ergebnis hinzuaddiert wird, also also 1222222*2+1=129.

Die Umwandlung kann mit einer Schleife realisiert werden, die jedes Bit der Binärzahl einzeln verarbeitet. Die Schleife hat genau 8 Durchgänge – einen für jedes Bit.

Die BCD-Zahl wird immer verdoppelt (X+X) und der Carry, sofern vorhanden, dazu addiert (X+X+C). So geht man insgesamt 8x durch die Schleife und erhält dann in der Ausgabe die BCD-Zahl für 129.

0+0+1(C)=1 ; Schritt 1 1+1=2 ; Schritt 2 2+2=4 ; Schritt 3 4+4=8 ; Schritt 4 8+8=16 ; Schritt 5 16+16=32 ; Schritt 6 32+32=64 ; Schritt 7 64+64+1(C) = 129 ; Schritt 8

Hier eine fertige Routine, für eine 16-Bit-Zahl

    sed                ; Dezimalmodus aktivieren (BCD-Arithmetik verwenden)
    lda #0             ; Lade 0 in den Akkumulator, um das Ergebnis zu initialisieren
    sta BCD+0          ; Setze das niedrigste BCD-Byte auf 0
    sta BCD+1          ; Setze das mittlere BCD-Byte auf 0
    sta BCD+2          ; Setze das höchste BCD-Byte auf 0
    ldx #16            ; Setze den X-Register auf 16, um 16 Bits der Eingabe zu verarbeiten

Loop:   asl BIN+0          ; Schiebe das niedrigste Byte der Binärzahl nach links (das höchste Bit geht in das Carry)
    rol BIN+1          ; Schiebe das höchste Byte der Binärzahl nach links und füge das Carry in Bit 0 ein
    lda BCD+0          ; Lade das niedrigste BCD-Byte in den Akkumulator
    adc BCD+0          ; Addiere das BCD-Byte zu sich selbst, inkl. Carry (neues Bit wird hinzugefügt)
    sta BCD+0          ; Speichere das Ergebnis zurück in das niedrigste BCD-Byte
    lda BCD+1          ; Lade das mittlere BCD-Byte in den Akkumulator
    adc BCD+1          ; Addiere das mittlere BCD-Byte zu sich selbst, inkl. propagierendem Carry
    sta BCD+1          ; Speichere das Ergebnis zurück in das mittlere BCD-Byte
    lda BCD+2          ; Lade das höchste BCD-Byte in den Akkumulator
    adc BCD+2          ; Addiere das höchste BCD-Byte zu sich selbst, inkl. propagierendem Carry
    sta BCD+2          ; Speichere das Ergebnis zurück in das höchste BCD-Byte
    dex                ; Dekrementiere den X-Register (ein Bit weniger zu verarbeiten)
    bne Loop           ; Springe zurück, solange noch Bits zu verarbeiten sind (X ≠ 0)

    cld                ; Schalte den Dezimalmodus aus (zurück zum Binärmodus)

BIN .byte $F5, $05      ; Eingabe Binär = $DC $05     = 1525 Dezimal
BCD .byte $00, $00, $00 ; Ausgabe BCD   = $25 $15 $00 = 1525 Dezimal

Meine Projekte findest Du hier...

... wunderbar... ihr seid einfach großartig!!

Dann ist meine Routine gar nicht mehr nötig... 😉

Dr. Irata schrieb: Das Problem dabei ist, daß man nur maximal den Wert 99 zum Score addieren kann und Subtraktion ist gar nicht implementiert.

Natürlich geht auch über 99. Einfach auf den 100er addieren. Und Subtrahieren ind BCD geht auch.

Visit https://www.wudsn.com the home of WUDSN IDE.

Sind getrennte Routinen für Rechnen und Darstellung eine Option?

Jede Info, die zu Hause auf meinem Rechner liegt habe ich unterwegs nicht verfügbar. Jede Info, die im Netz liegt finde ich nicht wieder, wenn ich sie benötige.

deine Idee mit der 16-Bit-Zahl und der schrittweisen Subtraktion von 10000, 1000 usw. ist sinnvoll und funktioniert gut für die Ziffernumwandlung. Alternativ könntest du auch eine Division und Modulo-Operation verwenden, um die Ziffern zu extrahieren – das ist oft kürzer und übersichtlicher. Zum Beispiel: Ziffer_i = (Wert / 10^i) % 10. Falls Performance nicht das größte Problem ist, ist das eine elegante Lösung.

Theoretisch ganz gute Idee, das Hauptproblem dabei ist natürlich immer die Division durch 10. Das ist einfach keine gute Zahl für den Computer. Man müsste jede Stelle einzeln extrahieren und dabei jeweils die Stelle nach ganz rechts schieben usw.... viel Rechenaufwand ...